package com.inspur.cloud.util;

import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

public class SshUtil { 
     
    private ChannelSftp channelSftp; 
     
    private ChannelExec channelExec; 
     
    private Session session = null; 
     
    private int timeout = 60000;
    
    private static final Logger logger = LoggerFactory.getLogger(SshUtil.class);
    //private static final Logger LOG = Logger.getLogger(sshUtil.class); 
     
    public SshUtil(SshConf conf) throws Exception 
    { 
    	logger.info("尝试连接到....host:" + conf.getHost() + ",username:" + conf.getUsername() +  ",port:" + conf.getPort());
        JSch jsch = new JSch(); // 创建JSch对象  
        session = jsch.getSession(conf.getUsername(), conf.getHost(), conf.getPort()); // 根据用户名，主机ip，端口获取一个Session对象  
        session.setPassword(conf.getPassword()); // 设置密码
        Properties config = new Properties();
        //下面一句配置本来是注释的，但在windows环境下使用时
        //connect一直连接不上，一直转圈圈，下面一句加上后就可以了。
        //不确定Linux下加上有什么影响。
        config.put("userauth.gssapi-with-mic", "no");
        //config.put("PreferredAuthentications","publickey,keyboard-interactive,password");
        config.put("StrictHostKeyChecking", "no");
//        session.setConfig(config); // 为Session对象设置properties
        if (StringUtils.isEmpty(conf.getPassword())) {//证书登陆
            logger.info("========================use id_rsa login========================");
            if (StringUtils.isEmpty(conf.getIdentity())) {
                conf.setIdentity("/root/.ssh/id_rsa");
            }
            jsch.addIdentity(conf.getIdentity(), conf.getPassphrase() != null ? conf.getPassphrase() : "");
            config.put("PreferredAuthentications", "publickey,keyboard-interactive,password");
            session.setConfig(config);
        } else {//密码登陆
            session.setPassword(conf.getPassword()); // 设置密码
            session.setConfig(config);
        }

        //session.setConfig("PreferredAuthentications","publickey,keyboard-interactive,password"); // 为Session对象设置properties  
        session.setTimeout(timeout); // 设置timeout时间
        session.connect(); // 通过Session建立链接
    }
     
    public void download(String src, String dst) throws Exception 
    { 
    	logger.info("---download1----");
        channelSftp = (ChannelSftp)session.openChannel("sftp"); 
        logger.info("--channelSftp--"+channelSftp);
        channelSftp.connect(); 
        logger.info("--src1--"+src);
        logger.info("--dst1--"+dst);
        channelSftp.get(src, dst, new FileProgressMonitor(), ChannelSftp.OVERWRITE); 
        logger.info("download1 ok");
        channelSftp.quit(); 
    }

    public void upload(String src, String dst) throws Exception 
    { 
        channelSftp = (ChannelSftp)session.openChannel("sftp"); 
        channelSftp.connect(); 
        channelSftp.put (src, dst, new FileProgressMonitor(), ChannelSftp.OVERWRITE); 
        channelSftp.quit(); 
    }

    public void runCmd(String cmd, String charset) throws Exception 
    { 
        try {
        	channelExec = (ChannelExec)session.openChannel("exec"); 
            channelExec.setCommand(cmd); 
            //channelExec.setInputStream(null);
            channelExec.setErrStream(System.err); 
            channelExec.connect(); 
            InputStream in = channelExec.getInputStream(); 
            BufferedReader reader = new BufferedReader(new InputStreamReader(in, Charset.forName(charset))); 
            String buf = null; 
            while ((buf = reader.readLine()) != null) 
            { 
                logger.info(buf); 
            } 
            reader.close(); 
            channelExec.disconnect(); 
        } catch(Exception e) {
        	logger.error("ssh" + e);
        }
    }

    public void runCmd(String cmd) throws Exception {
        runCmd(cmd, "UTF-8");
    }


    public String runCmdWithReturnInfo(String cmd, String charset) throws Exception
    {
        String result = "";
        try {
            channelExec = (ChannelExec)session.openChannel("exec");
            channelExec.setCommand(cmd);
            //channelExec.setInputStream(null);
            //channelExec.setErrStream(System.err);
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            channelExec.setErrStream(output);

            channelExec.connect();
            InputStream in = channelExec.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in, Charset.forName(charset)));
            String buf = null;
            while ((buf = reader.readLine()) != null)
            {
                logger.info(buf);
            }
            reader.close();

            result = output.toString();
            channelExec.disconnect();
        } catch(Exception e) {
            logger.error("ssh" + e);
        }
        return result;
    }


    public void close() 
    { 
        session.disconnect(); 
    } 
} 

